﻿#pragma once

#include "Framework/CommonHead.h"
#include "Framework/ApplicationSubsystem.h" 
#include "Widgets/Window.h"
#include "Framework/Tickable.h"
#include <stack>
#include "WindowManager.m.h"

RCLASS()
class WHENGINE_API RWindowManager : public RApplicationSubsystem , public ITickable
{
    ROBJECT
public:
    void Initialize() override;
    void Deinitialize() override;

    static RWindowManager* Get();

    RWindowPtr GetFirstWindow()
    {
        assert(!Windows.Empty() && "No window!");
        return Windows[0];
    }

    RWindowPtr FindWindow(uint64_t InWindowID)
    {
        for(auto Window:Windows)
        {
            if(Window->GetWindowID()==InWindowID)
            {
                return Window;
            }
        }

        return nullptr;
    }

    SIntPoint GetMouseScreenPosition();

    // RWindowPtr CreateWindow(TSubclassOf<RWindow> InClass
    //     ,TOptional<SIntPoint> InOverridePosition=TOptional<SIntPoint>()
    //     ,const SIntPoint & InOverrideSize=SIntPoint(300,300));

    //void DestroyWindow(RWindowPtr InWindow);
    
    virtual void Tick(float DeltaSeconds) override;

    //绘制所有窗口
    void PaintWindows();

    bool ProcessWindowEvent(const SWindowEvent & InEvent);


    bool ProcessMouseEvent(const SMouseButtonEvent& MouseEvent);
   

    bool ProcessTextInputEvent(const STextInputEvent& InputEvent) 
    {
        for(auto It=Windows.rbegin();It!=Windows.rend();It++)
        {
            auto Window=*It;
           if(InputEvent.GetWindowID()==Window->GetWindowID()  && Window->ProcessTextInput(InputEvent))
           {
               return true;
           }

           //modal window consume all event
           if(Window->bIsModalWindow)
           {
                break;
           }
        }

        return false;
    }


    bool  ProcessKeyboardEvent(const SKeyboardEvent& BoardkeyEvent) 
    {
        for(auto It=Windows.rbegin();It!=Windows.rend();It++)
        {
            auto Window=*It;
           if(BoardkeyEvent.WindowID==Window->GetWindowID()  && Window->ProcessKeyboardEvent(BoardkeyEvent))
           {
               return true;
           }

           //modal window consume all event
           if(Window->bIsModalWindow)
           {
                break;
           }
        }

        return false;
    }

    //for create a modal window, you should call MakeWindowModal after Show
    //for example:
    // auto ModalWindow= NewObject<RWindow>();
    // /* add some widget here */
    // ModalWindow->Show();
    // RWindowManager::Get()->MakeWindowModal(ModalWindow);
    void MakeWindowModal(RWindowPtr InWindow);

    bool HasAnyWindow();

    void RegisterWindow(RWindowPtr InWindow);
    void UnregisterWindow(RWindowPtr InWindow);

    TVector<RWindowPtr> GetWindows() const
    {
        return Windows;
    }
protected:

    TVector<RWindowPtr> Windows;

    std::stack<RWindowPtr> ModalWindows;

};